package com.woniuxy.joylifecenter.advice;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.github.houbb.sensitive.core.api.SensitiveUtil;

import com.woniuxy.common.entity.CenterLog;

import com.woniuxy.joylifecenter.annotation.SysLog;
import com.woniuxy.joylifecenter.service.LogService;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.CodeSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;



@Component
@Aspect
public class LogAdvice {
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private LogService logService;

    /**
     * @return java.lang.String
     * @Author ArmWatt
     * @Date 2020/4/29
     * @Param [joinPoint]
     * @Description 用于获取连接点操作名
     **/
    public String getMethodDesc(JoinPoint joinPoint) {
        //获取连接点的Class对象
        Class target = joinPoint.getTarget().getClass();
        //获取连接点方法签名
        CodeSignature signature = (CodeSignature) joinPoint.getSignature();
        //根据方法名和参数列表获取某个方法

        try {
            Method method = target.getMethod(joinPoint.getSignature().getName(), signature.getParameterTypes());
            String methodDesc = method.getAnnotation(SysLog.class).value();
            return methodDesc;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @return void
     * @Author ArmWatt
     * @Date 2020/4/29
     * @Param [joinPoint, methodDesc]
     * @Description 记录日志
     **/
    private void saveLog(JoinPoint joinPoint, String methodDesc) {
        //从权限框架获取验证用户
        //CenterUser centerUser = (CenterUser) SecurityUtils.getSubject().getPrincipal();
        //从Servlet获取访问者的ip
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        CenterLog centerLog = new CenterLog();
        try {
            centerLog.setCenterIp(request.getRemoteHost());
            //将方法参数列表转换成json串
            List params = Arrays.asList(joinPoint.getArgs());
            List result = SensitiveUtil.desJsonCollection(params);
            centerLog.setCenterParams(objectMapper.writeValueAsString(result));
            centerLog.setCenterLogid(UUID.randomUUID().toString().replaceAll("-",""));
            centerLog.setCenterMethod(joinPoint.getSignature().getName());
            centerLog.setCenterCreatetime(new Date());
            //此处用户名做测试用，整合权限框架后替换成真实用户名
            centerLog.setCenterUsername("testUser");
            centerLog.setCenterOperation(methodDesc);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            centerLog.setCenterParams(null);
        }
        //如果成功获取日志参数则记录日志
        logService.saveLog(centerLog);


    }

    /**
     * @return void
     * @Author ArmWatt
     * @Date 2020/4/29
     * @Param [joinPoint]
     * @Description 前置通知用于记录操作日志
     **/
    @Before(value = "@annotation(com.woniuxy.joylifecenter.annotation.SysLog)")
    public void operationLog(JoinPoint joinPoint) {

        this.saveLog(joinPoint, getMethodDesc(joinPoint));
    }

    /**
     * @return void
     * @Author ArmWatt
     * @Date 2020/4/29
     * @Param [joinPoint]
     * @Description 后置通知记录管理员登陆日志
     **/
//    @AfterReturning(value = "excution(此处是登陆方法路径，待补充)")
//    public void loginLog(JoinPoint joinPoint) {
//        this.saveLog(joinPoint, "后台管理员登陆");
//    }
}
